package org.msfj.common.util;

import cn.hutool.core.util.StrUtil;

import java.util.HashMap;
import java.util.Map;

public class CreditCodeUtil {

    private static int[] power = {1,3,9,27,19,26,16,17,20,29,25,13,8,24,10,30,28};
    // 社会统一信用代码不含（I、O、S、V、Z） 等字母
    private static char[] code = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H','J','K','L','M','N','P','Q','R','T','U','W','X','Y'};
    private static Map<String, Integer> codeMap = null;
    private static char[] pre17s;


//    static {
//        initCodeMap();
//    }

    /**
     * 判断是否是一个有效的社会信用代码
     * @param creditCode
     * @return
     */
    public static boolean validate(String creditCode) {
        if (StrUtil.isBlank(creditCode)) {
            return false;
        }
        if (creditCode.length() != 18) {
            return false;
        }
        if (creditCode.startsWith("000")) { //兼容输入不够18位的老注册号
            return true;
        }
        initCodeMap();
        pre17(creditCode);
        int sum = sum(pre17s);
        int temp = sum % 31;
        temp = temp == 0 ? 31 : temp;
        return creditCode.substring(17, 18).equals(String.valueOf(code[31 - temp]));
//        return true;
    }

    /**
     * @param chars
     * @return
     */
    private static int sum(char[] chars) {
        int sum = 0;
        for (int i = 0; i < chars.length; i++) {
            int code = codeMap.get(String.valueOf(chars[i]));
            sum += power[i] * code;
        }
        return sum;

    }

    /**
     * 获取前17位字符
     * @param creditCode
     */
    private static void pre17(String creditCode) {
        String pre17 = creditCode.substring(0, 17);
        pre17s = pre17.toCharArray();
    }

    /**
     * 初始化数据
     */
    private static void initCodeMap() {
        codeMap = new HashMap<>();
        for (int i = 0; i < code.length; i++) {
            codeMap.put(String.valueOf(code[i]), i);
        }
    }


    public static void main(String[] args) {
        System.out.println(validate("913706871653058810"));
        System.out.println(validate("916101395922271285"));
        System.out.println(validate("91610104MA6U0FDQ1Y"));
    }
}
